package com.liangtian.mdm.material.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liangtian.mdm.base.authentication.JWTUtil;
import com.liangtian.mdm.base.constants.ResultCode;
import com.liangtian.mdm.base.dao.JdbcDao;
import com.liangtian.mdm.base.response.BaseResponse;
import com.liangtian.mdm.dm.jsp.common.ExcelUtil;
import com.liangtian.mdm.material.common.util.ExcelExportUtil;
import com.liangtian.mdm.material.dao.WlFhDao;
import com.liangtian.mdm.material.model.WlFh;
import com.liangtian.mdm.material.service.WlFhService;
import com.liangtian.mdm.util.ExportUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 物料符号ServiceImpl
 *
 */
@SuppressWarnings({"unchecked", "rawtypes"})
@Service
public class WlFhServiceImpl implements WlFhService {

    @Autowired
    private WlFhDao wlFhDao;

    @Autowired
    private JdbcDao jdbcDao;

    /**
     * 获取物料符号列表
     * @param map
     * @return
     */
    @Transactional
    @Override
    public PageInfo getWlFhListByCond(Map<String, Object> map) {
        PageInfo<List<WlFh>> pageInfo = null;
        try {
            Object pNo = map.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(map.get("limit").toString());// 模型定义页面要显示数据条数
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）
            List<WlFh> wlFhMapList = wlFhDao.getWlFhListByCond(map);
            pageInfo = new PageInfo(wlFhMapList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }
    /**
     * 新增物料符号
     * @param wlfh
     * @return
     */
    @Override
    public int insertWlFh(WlFh wlfh) {
        return wlFhDao.insertWlFh(wlfh);
    }

    /**
     * 更新物料符号
     * @param wlfh
     */
    @Override
    public void updateWlFh(WlFh wlfh) {
        wlFhDao.updateWlFh(wlfh);
    }

    /**
     * 校验物料符号对象是否存在
     * @param wlfh
     * @return
     */
    @Override
    public int getWlFhExist(WlFh wlfh) {
        Map<String, Object> map = new HashMap<>();
        map.put("fhname", wlfh.getFhname());
        map.put("fhtype", wlfh.getFhtype());
        return wlFhDao.getWlFhExist(map);
    }

    /**
     * 根据Id查询物料符号
     * @param wlfh
     * @return
     */
    @Override
    public WlFh getWlFhById(WlFh wlfh) {
        return wlFhDao.getWlFhById(wlfh);
    }

    /**
     * 修改时校验物料符号对象是否存在
     * @param wlfh
     * @return
     */
    @Override
    public int checkWlFhExistByEdit(WlFh wlfh) {
        int i = 0;
        i = wlFhDao.checkWlFhExistByEdit(wlfh);
        return i;
    }

    /**
     * 批量删除物料物料符号
     * @param map
     * @return
     */
    @Override
    public int deleteWlFhByIds(Map<String, Object> map) {
        return wlFhDao.deleteWlFhByIds(map);
    }

    /**
     * 活动/冻结物料物料符号
     * @param wlfh
     */
    @Override
    public void updateWlFhStatus(WlFh wlfh) {
        wlFhDao.updateWlFhStatus(wlfh);
    }

    /**
     * 查询物料符号不分页情况下的列表
     * @param wlfh
     * @return
     */
    @Override
    public List<WlFh> getWlFhNoPageByCond(WlFh wlfh) {
        return wlFhDao.getWlFhNoPageByCond(wlfh);
    }

    /**
     * 校验用户输入的数据
     * @param valueList
     * @param tableName
     * @return
     */
    @Override
    public BaseResponse checkImportList(List<Object[]> valueList, String tableName) throws Exception{
        String fileName = "";
        BaseResponse baseResponse = new BaseResponse().ok();
        StringBuilder sb = new StringBuilder();
        valueList.remove(0);
        boolean importedDataHasExist = true;
        if (CollectionUtils.isNotEmpty(valueList)) {
            //获取用户将导入的数据n条
            for (int j = 0; j < valueList.size(); j++) {
                //获取行
                String[] row = (String[]) valueList.get(j);
                for (int k = 0; k < row.length; k++) {
                    //获取每固定行一列（0,0）
                    String cell = row[k];
                    sb.append(checkColumn(j, k, cell, row));
                }
            }
        } else {
            sb.append("@@@@" + "请在模板中填写需要导入的数据！");
            importedDataHasExist = false;
        }

        if (sb.toString().equals("")) {
            String[] headArray ={"USER_NAME","USER_ACCOUNT","USER_EMAIL","USER_PHONE","USER_TELEPHONE","ORGANIZATION_ID"};
            List<String> sqls = genSql(tableName, valueList, headArray);
            boolean sucess = jdbcDao.executeSqlList(sqls, true);
            if (sucess) {
                baseResponse = BaseResponse.genResponse(ResultCode.SUCCESS.getCode(), "导入成功!");
            }
        } else {
            fileName="wlFhImportError"+"@@@@"+new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date())+".txt";

                ExportUtil.errTxt(sb.toString(), fileName);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("errorFileName", fileName);
            if (importedDataHasExist){
                baseResponse = BaseResponse.genResponse(ResultCode.IMPORTED_DATA_HAS_EXIST, jsonObject);
            }else {
                baseResponse = BaseResponse.genResponse(ResultCode.IMPORTED_FILE_IS_EMPTY, jsonObject);
            }
        }
        return baseResponse;
    }

    /**
     * 检查列
     * @param row
     * @param column
     * @param cell
     * @param coll
     * @return
     */
    @Override
    public String checkColumn(int row, int column, String cell, String[] coll) {
        StringBuffer sb = new StringBuffer();//声明拼接符
        //校验每行数据的每一列，错误的拼接成string，正确的不拼接
        if (column == 0) {//说明是第一列（校验物料符号）
            if (cell.equals("") || cell == null || cell.equals(" ")) {//如果数据为空
                sb.append("@@导入数据第" + (row + 2) + "行,第" + (column + 1) + "列,物料符号不可为空！");
            } else {
                Map<String, Object> map = new HashMap<>();
                map.put("fhname", cell);
                map.put("fhtype", coll[1]);
                int count = wlFhDao.getWlFhExist(map);
                if (count > 0) {
                    sb.append("@@导入数据第" + (row + 2) + "行,第" + (column + 1) + "列,物料符号" + "'" + cell + "'" + "为" + "'" + coll[1] + "'" + "已存在，请修改物料符号或符号类型！");
                }
            }
        } else if (column == 1) {//说明是第二列（校验符号类型）
            if (cell.equals("") || cell == null || cell.equals(" ")) {
                sb.append("@@导入数据第" + (row + 2) + "行,第" + (column + 1) + "列,符号类型不可为空！");
            } else {
                if ("1".equals(cell) || "2".equals(cell) || "3".equals(cell)
                        || "前置符号".equals(cell) || "后置符号".equals(cell) || "连接符号".equals(cell)) {

                } else {
                    sb.append("@@导入数据第" + (row + 2) + "行,第" + (column + 1) + "列,符号类型输入错误!");
                }
            }
        }
        return sb.toString();
    }

    /**
     * 跟sql
     * @param tableName
     * @param subList
     * @param headArray
     * @return
     */
    @Override
    public List<String> genSql(String tableName, List<Object[]> subList, String[] headArray) {
//        SysUser user = ShiroSessionUtils.getSessionSysUser(ConstantBean.CURRENT_SESSION_USER);
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String userAccount = JWTUtil.getUsername(token);

        List<String> sqls = new ArrayList<String>();
        // 获取值集合
        for (int j = 0; j < subList.size(); j++) {
            StringBuffer sb = new StringBuffer("");
            sb.append(" insert into " + tableName + " (")
                    .append("FHNAME,FHTYPE,CREATER,CREATETIME,")
                    .append("STATUS)")
                   .append(" VALUES( ");

            String[] row = (String[]) subList.get(j);
            //拼接sql值
            sb.append("'").append(row[0]).append("',");

            if ("1".equals(row[1]) || "2".equals(row[1]) || "3".equals(row[1])) {
                sb.append("'").append(row[1]).append("',");
            } else if ("前置符号".equals(row[1])) {
                sb.append("'1',");
            } else if ("后置符号".equals(row[1])) {
                sb.append("'2',");
            } else if ("连接符号".equals(row[1])) {
                sb.append("'3',");
            }

            sb.append("'").append(userAccount).append("', ").append("sysdate(),")
                    .append("'1' )");
            sqls.add(sb.toString());
            System.out.print(sb.toString());
        }
        return sqls;
    }

    /**
     * 物料符号导出
     * @param list
     * @param response
     */
    @Override
    public void exportWlFh(List<WlFh> list, HttpServletResponse response) {
        try {
            String tablename = "物料符号";
            // 声明一个工作薄
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("物料符号");
            XSSFRow row = sheet.createRow(0);
            XSSFCell cell = null;
            CellStyle style = ExcelUtil.createCellTextStyle(workbook);
            cell = row.createCell(0);
            sheet.setDefaultColumnStyle(0, style);
            cell.setCellValue("符号");
            cell = row.createCell(1);
            sheet.setDefaultColumnStyle(1, style);
            cell.setCellValue("符号类型");
            cell = row.createCell(2);
            sheet.setDefaultColumnStyle(2, style);
            cell.setCellValue("状态");
            for (int i = 0; i < list.size(); i++) {
                WlFh getWlLb = list.get(i);
                row = sheet.createRow(i + 1);
                cell = row.createCell(0);
                sheet.setDefaultColumnStyle(0, style);
                cell.setCellValue(getWlLb.getFhname());
                cell = row.createCell(1);
                sheet.setDefaultColumnStyle(1, style);
                String leix = "";
                if ("1".equals(getWlLb.getFhtype())) {
                    leix = "前置符号";
                } else if ("2".equals(getWlLb.getFhtype())) {
                    leix = "后置符号";
                } else {
                    leix = "连接符号";
                }
                cell.setCellValue(leix);
                cell = row.createCell(2);
                sheet.setDefaultColumnStyle(2, style);
                cell.setCellValue(getWlLb.getStatus().equals("1") ? "活动" : "冻结");
            }
            ExcelExportUtil.outExportExcel(tablename, workbook, response);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取物料符号列表2
     * @param map
     * @return
     */
    @Override
    public PageInfo getWlFhListByCond2(Map<String, Object> map) {
        PageInfo<List<WlFh>> pageInfo = null;
        try {
            Object pNo = map.get("pageNum");
            int pageNum, pageSize;
            // export
            if (pNo != null && !"NaN".equals(pNo)) {
                pageNum = Integer.parseInt(pNo.toString());// 页码
            } else {
                pageNum = 1;
            }
            // pageSize=0时不分页
            pageSize = Integer.parseInt(map.get("limit").toString());// 模型定义页面要显示数据条数
            // 例如
            // 10,20,50,100
            PageHelper.startPage(pageNum, pageSize);// 开始分页标志（当前页，显示条数）
            List<WlFh> wlFhMapList = wlFhDao.getWlFhListByCond(map);
            pageInfo = new PageInfo(wlFhMapList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageInfo;
    }

    /**
     * 根据主键校验类别模板特征量符号
     * @param map
     * @return
     */
    @Override
    public int checkLbmbTzlFhByFhWym(Map<String, Object> map) {
        return this.wlFhDao.checkLbmbTzlFhByFhWym(map);
    }

}
